package yxy.game.pm2.active.command.actpay;

import org.joda.time.DateTime;
import yxy.apple.logger.Logger;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.actmondiscount;
import yxy.cherry.data.bean.charge;
import yxy.cherry.game.base.message.MessageEmitterHandler;
import yxy.cherry.game.base.message.annotation.MessageSource;
import yxy.cherry.game.base.message.annotation.MessageType;
import yxy.game.pm2.Result;
import yxy.game.pm2.active.module.ActiveModule_每月特惠;
import yxy.game.pm2.active.module.actdata.ActDataCenter;
import yxy.game.pm2.active.module.subordinateclass.DataIdOrderId;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.command.Command;
import yxy.game.pm2.message.PackageMessage;
import yxy.game.pm2.message.PayMessage;
import yxy.game.pm2.message.PayMessage.MonthPayInfoRequest;
import yxy.game.pm2.module.CurrencyHandle;

import java.util.*;

/**
 * 支付活动 - 每月特惠
 *
 * @author Dell
 */
@MessageType(proto = Command.MonthPayInfo, classtype = PayMessage.MonthPayInfoRequest.class)
public class CMD_Active_每月特惠_Info extends Command<MonthPayInfoRequest> {

    private static final Logger logger = Logger.create(CMD_Active_每月特惠_Info.class);

    @Override
    public void execute(MessageSource messageSource, MonthPayInfoRequest request) throws Exception {
        String pcode = messageSource.getTag();

        PayMessage.MonthPayInfoResponse.Builder response = PayMessage.MonthPayInfoResponse.newBuilder();

        try {
            handle_每月特惠(messageSource, response, pcode);
            return;
        } catch (Exception e) {
            e.printStackTrace();
        }

        send(messageSource, response, Result.DataError);
    }

    private void send(MessageSource messageSource, PayMessage.MonthPayInfoResponse.Builder response, Result result) {
        response.setResult(result.packResult());
        MessageEmitterHandler.getInstance().send(messageSource, response.build());
    }


    /**
     * 每月特惠的礼包入口逻辑
     *
     * @param messageSource
     * @param response
     * @param pcode
     */
    public void handle_每月特惠(MessageSource messageSource, PayMessage.MonthPayInfoResponse.Builder response, String pcode) {
        //初始礼包为空，只有时间字段
        ActiveModule_每月特惠 am = ActiveModule_每月特惠.get(pcode, false);

        if (am == null) {
            send(messageSource, response, Result.ActNoOpen);
            return;
        }

        //已经买过的礼包
        ArrayList<DataIdOrderId> finishs = am.getFinish();
        ArrayList<DataIdOrderId> locks = am.getLock();

        //礼包list
        ArrayList<PayMessage.ActivePay> cantBuyList = new ArrayList<>();
        ArrayList<PayMessage.ActivePay> canBuyList = new ArrayList<>();

        //礼包的表
        Map<String, actmondiscount> amcs = ActDataCenter.getAllData(actmondiscount.class, pcode);
        for (actmondiscount data : amcs.values()) {

            //第一组的礼包
            PayMessage.ActivePay.Builder builder = firstGroupAps(data, finishs, locks, response, cantBuyList, canBuyList);
            //判断是否展示下一级礼包
            nextGroupAps(response, data, builder, finishs, locks, pcode, cantBuyList, canBuyList);

        }

        //给礼包排序，价格低到高
        Collections.sort(canBuyList, new Comparator<PayMessage.ActivePay>() {
            @Override
            public int compare(PayMessage.ActivePay o1, PayMessage.ActivePay o2) {
                return  o1.getMoney()-o2.getMoney();
            }
        });

        Collections.sort(cantBuyList, new Comparator<PayMessage.ActivePay>() {
            @Override
            public int compare(PayMessage.ActivePay o1, PayMessage.ActivePay o2) {
                return  o1.getMoney()-o2.getMoney();
            }
        });

        response.addAllAps(canBuyList);
        response.addAllAps(cantBuyList);
        response.setEnd(am.getRoundend().getMillis());
        send(messageSource, response, Result.Success);
    }


    /**
     * 第一组礼包
     *
     * @param data
     * @param finishs
     * @param locks
     * @param response
     * @param cantBuyList
     * @param canBuyList
     * @return
     */
    private PayMessage.ActivePay.Builder firstGroupAps(actmondiscount data, ArrayList<DataIdOrderId> finishs, ArrayList<DataIdOrderId> locks, PayMessage.MonthPayInfoResponse.Builder response, ArrayList<PayMessage.ActivePay> cantBuyList, ArrayList<PayMessage.ActivePay> canBuyList) {
        //一开始初始化第一组的，后面的礼包等买完才判断展不展示下一级礼包
        if (data.getGroup() != 1) return null;

        //封装返回
        PayMessage.ActivePay.Builder builder = returnAps(data, finishs, locks, response);

        //礼包返回
        if (builder.getCanbuynum() <= 0) {
            cantBuyList.add(builder.build());
        } else {
            canBuyList.add(builder.build());
        }

        return builder;
    }

    /**
     * 下一级礼包
     *
     * @param response
     * @param data
     * @param builder
     * @param finishs
     * @param locks
     * @param pcode
     * @param cantBuyList
     * @param canBuyList
     */
    private void nextGroupAps(PayMessage.MonthPayInfoResponse.Builder response, actmondiscount data, PayMessage.ActivePay.Builder builder, ArrayList<DataIdOrderId> finishs, ArrayList<DataIdOrderId> locks, String pcode, ArrayList<PayMessage.ActivePay> cantBuyList, ArrayList<PayMessage.ActivePay> canBuyList) {
        if (builder == null) return;

        //没买完就不执行展示下一礼包逻辑
        while (true) {
            if (builder.getCanbuynum() > 0) return;

            //没有下一级礼包就不执行逻辑
            if (data.getNextid() == 0) return;

            //下一级的礼包
            actmondiscount nextdata = ActDataCenter.getData(data.getNextid(), actmondiscount.class, pcode);

            //礼包封装
            PayMessage.ActivePay.Builder nextBuilder = returnAps(nextdata, finishs, locks, response);

            //礼包返回
            if (nextBuilder.getCanbuynum() <= 0) {
                cantBuyList.add(nextBuilder.build());
            } else {
                canBuyList.add(nextBuilder.build());
            }


            builder = nextBuilder;
            data = nextdata;

            //没有下一级就返回
            if (nextdata.getNextid() == 0) return;
        }

    }


    /**
     * 封装礼包
     *
     * @param data
     * @param finishs
     * @param locks
     * @param response
     */
    public PayMessage.ActivePay.Builder returnAps(actmondiscount data, ArrayList<DataIdOrderId> finishs, ArrayList<DataIdOrderId> locks, PayMessage.MonthPayInfoResponse.Builder response) {
        PayMessage.ActivePay.Builder build = PayMessage.ActivePay.newBuilder();

        int chargeid = data.getChargeid();
        charge goodPrice = DataCenter.getData(chargeid, charge.class); //商品价格
        int limit = data.getNum();
        int[] rewardtypes = data.getRewardtype();
        int[] rewardids = data.getRewardid();
        int[] rewardnums = data.getRewardnum();

        build.setGoodsid(chargeid);
        build.setLimit(limit);

        build.setGoodsPrice(goodPrice.getDismoney()); //商品价格
        build.setMoney(goodPrice.getMoney());
        build.setRebate(data.getRebate()); //返利倍数
        Collection<Currency> curs = Currency.create(rewardtypes, rewardids, rewardnums);
        Collection<PackageMessage.Item> items = new CurrencyHandle().packItems(curs);

        build.addAllCur(items);

        int finish = 0;
        for (int i = 0; i < finishs.size(); i++) {
            DataIdOrderId finishdio = finishs.get(i);
            if (finishdio.getDataid() == chargeid) {
                HashMap<String, DateTime> odmap = finishdio.getMyorderinfoMap();
                if (odmap == null) {
                    continue;
                }
                finish = odmap.size();
            }
        }

        int lock = 0;
        for (int i = 0; i < locks.size(); i++) {
            DataIdOrderId lockdio = locks.get(i);
            if (lockdio.getDataid() == chargeid) {
                HashMap<String, DateTime> odmap = lockdio.getMyorderinfoMap();
                if (odmap == null) {
                    continue;
                }

                lock = odmap.size();
            }
        }

        int canbuynum = limit - finish - lock;
        canbuynum = canbuynum < 0 ? 0 : canbuynum;

        build.setCanbuynum(canbuynum);

        return build;
    }

}
